package at.technikum_wien.embsys.aat.PriscillaCore.component;

import java.util.List;

import at.technikum_wien.embsys.aat.PriscillaCore.enums.EnoceanComponentType;
import at.technikum_wien.embsys.aat.PriscillaCore.telegram.Telegram;



/**
 * 
 * EEP_07_13_05 component class - environmental applications
 *
 * Type: environmental applications - direction exchange
 * Elevation: -90 - +90°
 * Azimut: 0-359°
 * 
 * @author B. Aigner
 * 
 */
public class EEP_07_13_05 implements EnoceanComponent {
	
	Telegram telegram;
	List<?> eventListener;
	
	int elevation = -300;
	int azimut = -300;
	
	int identifier;
	
	EnoceanComponentType enoceanComponentType = EnoceanComponentType.EEP_07_13_05;
	boolean telegramCreation = false;

	/**
	 * This constructor is used for received packets.
	 * It will parse the telegram and set the corresponding members.
	 * 
	 * @param telegram Received Telegram
	 * @param listener Event subscriber list
	 */
	public EEP_07_13_05(Telegram telegram, List<?> listener) {
		super();
		this.telegram = telegram;
		this.eventListener = listener;
		
		elevation = telegram.getData3() - 90;
		
		azimut = telegram.getData1() + ((telegram.getData2() & 0x01) * 256);
		
		identifier = (telegram.getData0() & 0xF0) / 16;
		fireFrame();
	}

	/**
	 * Fire all associated events
	 */
	void fireFrame() {
		//TODO: WeatherStation Event
		/*Iterator listen = eventListener.iterator();
		final FrameEventFan frameEventFan = new FrameEventFan(this, telegram.getDeviceID(), this.fanspeed, this.fantype );
		while (listen.hasNext()) {
			((LinkListener) listen.next()).frameReceived_Fan(frameEventFan);
		}
		*/
	}

	/**
	 * Void constructor. It is used to create a new telegram for sending
	 */
	public EEP_07_13_05() {
		super();
		telegram = new Telegram();
		telegramCreation = true;
	}

	/**
	 * This constructor is used to create a telegram (the device id is given as parameter)
	 * @param deviceID Full device ID
	 */
	public EEP_07_13_05(String deviceID) {
		super();
		telegram = new Telegram();
		telegram.setDeviceID(deviceID);
		telegramCreation = true;
	}
	
	boolean checkBit(int value, int bitNr) {
		return (value & (1 << bitNr)) != 0;
	}
	
	int setBit(int value, int bitNr) {
		return value | (1<<bitNr);
	}
	
	int clrBit(int value, int bitNr) {
		return value & (~(1<<bitNr));
	}
	
	@Override
	public String getDeviceID() {
		return telegram.getDeviceID();
	}
	@Override
	public String getORG() {
		return telegram.getxORG();
	}
	@Override
	public EnoceanComponentType getType() {
		return enoceanComponentType;
	}

	@Override
	public void setDeviceID(String deviceID) {
		telegram.setDeviceID(deviceID);
	}

	/**
	 * Creates a new telegram from the component
	 * 
	 * This method creates a new telegram (if the component is initialized with
	 * a constructor without a telegram as parameter) or returns the saved telegram.
	 * The new telegram is built up from the members in this class (in this case environmental data). 
	 * @return Created telegram
	 */
	public Telegram getTelegram() {
		if(telegramCreation == true) {
			telegram.setData3(elevation + 90);
			telegram.setData2((azimut & 0x0100) / 256);
			telegram.setData1(azimut & 0x00FF);
			
			telegram.setData0(identifier * 16);
		}
		return telegram;
	}

	public int getElevation() {
		return elevation;
	}

	public int getAzimut() {
		return azimut;
	}

	public int getIdentifier() {
		return identifier;
	}

	public void setElevation(int elevation) {
		if(elevation > 90) return;
		if(elevation < -90) return;
		this.elevation = elevation;
	}

	public void setAzimut(int azimut) {
		if(azimut > 359) return;
		if(azimut < 0) return;
		this.azimut = azimut;
	}

	public void setIdentifier(int identifier) {
		if(identifier > 15) return;
		this.identifier = identifier;
	}
}
